package fr.emse.tatiana.replayable.analysis.graph;

import java.beans.PropertyChangeSupport;
import java.util.List;

import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;

import fr.emse.tatiana.graphical.DisplayRule;
import fr.emse.tatiana.replayable.Anchor;
import fr.emse.tatiana.replayable.analysis.GraphAnalysis;
import fr.emse.tatiana.replayable.analysis.Link;

public class EventGraphPart extends AbstractGraphicalEditPart {

	private EventGraphFigure f;
	private PropertyChangeSupport listeners;

	public EventGraphPart(Anchor a) {
		super();
		setModel(a);
		this.listeners = new PropertyChangeSupport(this);
	}

	public Anchor getAnchor() {
		return (Anchor) getModel();
	}
	
	public GraphAnalysis getAnalysis() {
		return ((GraphAnalysisPart) getParent()).getAnalysis(); 
	}
	
	@Override
	protected IFigure createFigure() {
		f = new EventGraphFigure();
		return f;
	}

	@Override
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.NODE_ROLE, new AppEditPolicy());
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new GraphicalNodeEditPolicy() {
			/* (non-Javadoc)
			 * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy#getConnectionCompleteCommand(org.eclipse.gef.requests.CreateConnectionRequest)
			 */
			@Override
			protected Command getConnectionCompleteCommand(CreateConnectionRequest request) {
				ConnectionCreateCommand cmd 
					= (ConnectionCreateCommand) request.getStartCommand();
				EventGraphPart part = (EventGraphPart) getHost();
				cmd.setTarget(part.getAnalysis(),part.getAnchor());
				return cmd;
			}
			/* (non-Javadoc)
			 * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy#getConnectionCreateCommand(org.eclipse.gef.requests.CreateConnectionRequest)
			 */
			@Override
			protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
				EventGraphPart part = (EventGraphPart) getHost();
				int style = ((Integer) request.getNewObjectType()).intValue();
				ConnectionCreateCommand cmd = new ConnectionCreateCommand(part.getAnalysis(), part.getAnchor(), style);
				request.setStartCommand(cmd);
				return cmd;
			}
			/* (non-Javadoc)
			 * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy#getReconnectSourceCommand(org.eclipse.gef.requests.ReconnectRequest)
			 */
			@Override
			protected Command getReconnectSourceCommand(ReconnectRequest request) {
				Link link = (Link) request.getConnectionEditPart().getModel();
				EventGraphPart part = (EventGraphPart) getHost();
				ConnectionReconnectCommand cmd = new ConnectionReconnectCommand(link);
				cmd.setNewSource(part.getAnalysis(),part.getAnchor());
				return cmd;
			}
			/* (non-Javadoc)
			 * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy#getReconnectTargetCommand(org.eclipse.gef.requests.ReconnectRequest)
			 */
			@Override
			protected Command getReconnectTargetCommand(ReconnectRequest request) {
				Link link = (Link) request.getConnectionEditPart().getModel();
				EventGraphPart part = (EventGraphPart) getHost();
				ConnectionReconnectCommand cmd = new ConnectionReconnectCommand(link);
				cmd.setNewTarget(part.getAnalysis(),part.getAnchor());
				return cmd;
			}
		});
	}
	
	protected ConnectionAnchor getConnectionAnchor() {

		return new ChopboxAnchor(getFigure());

	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections()
	 */
	@Override
	protected List getModelSourceConnections() {
		return getAnalysis().getSourceConnections(getAnchor());
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections()
	 */
	@Override
	protected List getModelTargetConnections() {
		return getAnalysis().getTargetConnections(getAnchor());
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef.ConnectionEditPart)
	 */
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
		return getConnectionAnchor();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef.Request)
	 */
	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		return getConnectionAnchor();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef.ConnectionEditPart)
	 */
	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {
		return getConnectionAnchor();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.gef.NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef.Request)
	 */
	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		return getConnectionAnchor();
	}
	
	@Override
	protected void refreshVisuals() {
		f.setText(getAnalysis().getText(getAnchor()));
		f.setLayout(getAnalysis().getPosition(getAnchor()));

		
		//default values
		f.setVisible(true);
		f.setBorderColor(ColorConstants.black);
		f.setBackgroundColor(ColorConstants.white);
		f.setShape(new RectangleFigure());
		
		List<DisplayRule> rules = getAnalysis().getRules();
        for (DisplayRule rule: rules) {
        	rule.apply(getAnalysis(), getAnchor(), f);
        }
        f.validate();

	}

}
